home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / clang / cujaug93.zip / TWILLING.ZIP / EXCERPTS.C next >
Text File  |  1993-02-25  |  3KB  |  87 lines

  1. // EXCERPTS:  The two crucial routines from the "JD2GREG.C" module, without
  2. //            the auxiliary functions and all the blather.......
  3.  
  4.  
  5. /**********************(  GREGORIAN CALENDAR MODULE )**************************
  6.  
  7.  
  8. Routines for converting between Gregorian Calendar dates and Julian Days, for
  9. validating date input, for date arithmetic, and for learning day of the week
  10. and of the year.
  11.  
  12. (c) 1991, 1993 by Bob Twilling.  
  13. C Users Journal readers may use this code for any purpose.
  14.  
  15. /----------------------------------------------------------------------------*/
  16.  
  17. #include       <stdlib.h>                 //for div()
  18.  
  19. typedef struct { short   mo;
  20.                  short   dy;
  21.                  short   yr; }  MDY;
  22.  
  23.  
  24. /*=======================(  MONTH TO DAY-OF-YEAR  )===========================/
  25.  
  26. Given a month, calc day of year up until.  Change to #if 0 to save 24 bytes 
  27. of near heap at a slight speed cost.                                         */
  28.  
  29. #if 1  
  30.    static short m2doy[] = 
  31.                 { 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337 };
  32.    #define M2DOY(mo)  (m2doy[mo-1])
  33. #else
  34.    #define M2DOY(mo)  ((((mo) * 979) >> 5) - 30)
  35. #endif
  36.  
  37.  
  38. /*=========================(  GREGORIAN TO JD  )==============================/
  39.  
  40. Given a month, day, and year, returns a long integer -- the Julian Day number
  41. at noon of that date.                                                        */
  42.  
  43. extern long greg2jd( short mo, short dy, short yr )  {
  44.  
  45.    short lp;
  46.  
  47. if ((mo -= 2) <= 0) { mo += 12; yr--; }   // 1> Roll-under the date
  48. dy += M2DOY(mo);                          // 2> Calc day of year
  49. lp = yr >> 2;                             // 3> Add and subtract leap days
  50. dy += lp;
  51. lp /= 25;
  52. dy -= lp;
  53. dy += lp >> 2;
  54. return (long)yr * 365 + dy + 1721119;  }  // 4> One div, one mul!
  55.  
  56.  
  57. /*=========================(  JD TO GREGORIAN  )==============================/
  58.  
  59. Given a long Julian Day and a pointer to a month-day-year structure, fills in
  60. that structure with the calendar date and returns the same pointer to it.    */
  61.  
  62. extern MDY * jd2greg( long jd, MDY * date )  {
  63.  
  64.    unsigned short x, y, d;
  65.    div_t          sd;                        //div and mod at the same time
  66.  
  67. y = 1600; jd -= 2305507;                     // 1> new origin 0 = 2/29/1600
  68. while (jd > 0)  { y += 400; jd -= 146097; }  // 2> lop off 400-yr blocks
  69. do { y -= 100; } while ((jd += 36524) < 0);  //    and add back 100-yr ones
  70. d = (unsigned short)jd;                      // 3> within 16-bit range now
  71. x = d / 1461;                                //    pity taint no ANSI udiv()
  72. y += x << 2;                                 //    note 4-yr blocks
  73. d -= x * 1461;                               //    and lop them off
  74. sd = div( d, 365);                           //    does % and / in same op
  75. date->yr = y + sd.quot;                      //    got years, provisionally
  76. d = ++sd.rem;                                // 4> day-of-year (base 1)
  77. if (sd.quot == 4)  { date->yr--; d = 366; }  //    case we hit a leap-year
  78. x = ((d + 30) << 5) / 979;                   //    x = month, March is 1
  79. date->dy = d - M2DOY(x);                     //    got day of month
  80. if ((x += 2) > 12)  { date->yr++; x -= 12; } // 5> roll around Jan and Feb 
  81. date->mo = x;                                //    got month
  82. return(date);  }
  83.  
  84.  
  85. /*==================================================================ENDIT====*/
  86.  
  87.